home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / cl_fx.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-24  |  56.5 KB  |  2,680 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // cl_fx.c -- entity effects parsing and management
  21.  
  22. #include "client.h"
  23.  
  24. void CL_LogoutEffect (vec3_t org, int type);
  25. void CL_ItemRespawnParticles (vec3_t org);
  26.  
  27. static vec3_t avelocities [NUMVERTEXNORMALS];
  28.  
  29. /*
  30. ==============================================================
  31.  
  32. LIGHT STYLE MANAGEMENT
  33.  
  34. ==============================================================
  35. */
  36.  
  37. typedef struct
  38. {
  39.     int        length;
  40.     float    value[3];
  41.     float    map[MAX_QPATH];
  42. } clightstyle_t;
  43.  
  44. clightstyle_t    cl_lightstyle[MAX_LIGHTSTYLES];
  45. int            lastofs;
  46.  
  47. /*
  48. ================
  49. CL_ClearLightStyles
  50. ================
  51. */
  52. void CL_ClearLightStyles (void)
  53. {
  54.     memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
  55.     lastofs = -1;
  56. }
  57.  
  58. /*
  59. ================
  60. CL_RunLightStyles
  61. ================
  62. */
  63. void CL_RunLightStyles (void)
  64. {
  65.     int        ofs;
  66.     int        i;
  67.     clightstyle_t    *ls;
  68.  
  69.     ofs = cl.time / 100;
  70.     if (ofs == lastofs)
  71.         return;
  72.     lastofs = ofs;
  73.  
  74.     for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
  75.     {
  76.         if (!ls->length)
  77.         {
  78.             ls->value[0] = ls->value[1] = ls->value[2] = 1.0;
  79.             continue;
  80.         }
  81.         if (ls->length == 1)
  82.             ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0];
  83.         else
  84.             ls->value[0] = ls->value[1] = ls->value[2] = ls->map[ofs%ls->length];
  85.     }
  86. }
  87.  
  88.  
  89. void CL_SetLightstyle (int i)
  90. {
  91.     char    *s;
  92.     int        j, k;
  93.  
  94.     s = cl.configstrings[i+CS_LIGHTS];
  95.  
  96.     j = strlen (s);
  97.     if (j >= MAX_QPATH)
  98.         Com_Error (ERR_DROP, "svc_lightstyle length=%i", j);
  99.  
  100.     cl_lightstyle[i].length = j;
  101.  
  102.     for (k=0 ; k<j ; k++)
  103.         cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a');
  104. }
  105.  
  106. /*
  107. ================
  108. CL_AddLightStyles
  109. ================
  110. */
  111. void CL_AddLightStyles (void)
  112. {
  113.     int        i;
  114.     clightstyle_t    *ls;
  115.  
  116.     for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
  117.         V_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]);
  118. }
  119.  
  120. /*
  121. ==============================================================
  122.  
  123. DLIGHT MANAGEMENT
  124.  
  125. ==============================================================
  126. */
  127.  
  128. cdlight_t        cl_dlights[MAX_DLIGHTS];
  129.  
  130. /*
  131. ================
  132. CL_ClearDlights
  133. ================
  134. */
  135. void CL_ClearDlights (void)
  136. {
  137.     memset (cl_dlights, 0, sizeof(cl_dlights));
  138. }
  139.  
  140. /*
  141. ===============
  142. CL_AllocDlight
  143.  
  144. ===============
  145. */
  146. cdlight_t *CL_AllocDlight (int key)
  147. {
  148.     int        i;
  149.     cdlight_t    *dl;
  150.  
  151. // first look for an exact key match
  152.     if (key)
  153.     {
  154.         dl = cl_dlights;
  155.         for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
  156.         {
  157.             if (dl->key == key)
  158.             {
  159.                 memset (dl, 0, sizeof(*dl));
  160.                 dl->key = key;
  161.                 return dl;
  162.             }
  163.         }
  164.     }
  165.  
  166. // then look for anything else
  167.     dl = cl_dlights;
  168.     for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
  169.     {
  170.         if (dl->die < cl.time)
  171.         {
  172.             memset (dl, 0, sizeof(*dl));
  173.             dl->key = key;
  174.             return dl;
  175.         }
  176.     }
  177.  
  178.     dl = &cl_dlights[0];
  179.     memset (dl, 0, sizeof(*dl));
  180.     dl->key = key;
  181.     return dl;
  182. }
  183.  
  184. /*
  185. ===============
  186. CL_NewDlight
  187. ===============
  188. */
  189. void CL_NewDlight (int key, float x, float y, float z, float radius, float time)
  190. {
  191.     cdlight_t    *dl;
  192.  
  193.     dl = CL_AllocDlight (key);
  194.     dl->origin[0] = x;
  195.     dl->origin[1] = y;
  196.     dl->origin[2] = z;
  197.     dl->radius = radius;
  198.     dl->die = cl.time + time;
  199. }
  200.  
  201.  
  202. /*
  203. ===============
  204. CL_RunDLights
  205.  
  206. ===============
  207. */
  208. void CL_RunDLights (void)
  209. {
  210.     int            i;
  211.     cdlight_t    *dl;
  212.  
  213.     dl = cl_dlights;
  214.     for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
  215.     {
  216.         if (!dl->radius)
  217.             continue;
  218.         
  219.         if (dl->die < cl.time)
  220.         {
  221.             dl->radius = 0;
  222.             return;
  223.         }
  224.         dl->radius -= cls.frametime*dl->decay;
  225.         if (dl->radius < 0)
  226.             dl->radius = 0;
  227.     }
  228. }
  229.  
  230. /*
  231. ==============
  232. CL_ParseMuzzleFlash
  233. ==============
  234. */
  235. void CL_ParseMuzzleFlash (void)
  236. {
  237.     vec3_t        fv, rv;
  238.     cdlight_t    *dl;
  239.     int            i, weapon;
  240.     centity_t    *pl;
  241.     int            silenced;
  242.     float        volume;
  243.     char        soundname[64];
  244.  
  245.     i = MSG_ReadShort (&net_message);
  246.     if (i < 1 || i >= MAX_EDICTS)
  247.         Com_Error (ERR_DROP, "CL_ParseMuzzleFlash: bad entity");
  248.  
  249.     weapon = MSG_ReadByte (&net_message);
  250.     silenced = weapon & MZ_SILENCED;
  251.     weapon &= ~MZ_SILENCED;
  252.  
  253.     pl = &cl_entities[i];
  254.  
  255.     dl = CL_AllocDlight (i);
  256.     VectorCopy (pl->current.origin,  dl->origin);
  257.     AngleVectors (pl->current.angles, fv, rv, NULL);
  258.     VectorMA (dl->origin, 18, fv, dl->origin);
  259.     VectorMA (dl->origin, 16, rv, dl->origin);
  260.     if (silenced)
  261.         dl->radius = 100 + (rand()&31);
  262.     else
  263.         dl->radius = 200 + (rand()&31);
  264.     dl->minlight = 32;
  265.     dl->die = cl.time; // + 0.1;
  266.  
  267.     if (silenced)
  268.         volume = 0.2;
  269.     else
  270.         volume = 1;
  271.  
  272.     switch (weapon)
  273.     {
  274.     case MZ_BLASTER:
  275.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  276.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
  277.         break;
  278.     case MZ_BLUEHYPERBLASTER:
  279.         dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1;
  280.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
  281.         break;
  282.     case MZ_HYPERBLASTER:
  283.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  284.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
  285.         break;
  286.     case MZ_MACHINEGUN:
  287.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  288.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  289.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
  290.         break;
  291.     case MZ_SHOTGUN:
  292.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  293.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0);
  294.         S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1);
  295.         break;
  296.     case MZ_SSHOTGUN:
  297.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  298.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0);
  299.         break;
  300.     case MZ_CHAINGUN1:
  301.         dl->radius = 200 + (rand()&31);
  302.         dl->color[0] = 1;dl->color[1] = 0.25;dl->color[2] = 0;
  303.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  304.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
  305.         break;
  306.     case MZ_CHAINGUN2:
  307.         dl->radius = 225 + (rand()&31);
  308.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
  309.         dl->die = cl.time  + 0.1;    // long delay
  310.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  311.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
  312.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  313.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.05);
  314.         break;
  315.     case MZ_CHAINGUN3:
  316.         dl->radius = 250 + (rand()&31);
  317.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  318.         dl->die = cl.time  + 0.1;    // long delay
  319.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  320.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
  321.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  322.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.033);
  323.         Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
  324.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.066);
  325.         break;
  326.     case MZ_RAILGUN:
  327.         dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0;
  328. //        S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0);
  329.         break;
  330.     case MZ_ROCKET:
  331.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
  332.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0);
  333.         S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1);
  334.         break;
  335.     case MZ_GRENADE:
  336.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
  337.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0);
  338.         S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1);
  339.         break;
  340.     case MZ_BFG:
  341.         dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
  342.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0);
  343.         break;
  344.  
  345.     case MZ_LOGIN:
  346.         dl->color[0] = 0;dl->color[1] = 1; dl->color[2] = 0;
  347.         dl->die = cl.time + 1.0;
  348.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
  349.         CL_LogoutEffect (pl->current.origin, weapon);
  350.         break;
  351.     case MZ_LOGOUT:
  352.         dl->color[0] = 1;dl->color[1] = 0; dl->color[2] = 0;
  353.         dl->die = cl.time + 1.0;
  354.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
  355.         CL_LogoutEffect (pl->current.origin, weapon);
  356.         break;
  357.     case MZ_RESPAWN:
  358.         dl->color[0] = 1;dl->color[1] = 1; dl->color[2] = 0;
  359.         dl->die = cl.time + 1.0;
  360.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
  361.         CL_LogoutEffect (pl->current.origin, weapon);
  362.         break;
  363.     // RAFAEL
  364.     case MZ_PHALANX:
  365.         dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5;
  366.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/plasshot.wav"), volume, ATTN_NORM, 0);
  367.         break;
  368.     // RAFAEL
  369.     case MZ_IONRIPPER:    
  370.         dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5;
  371.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rippfire.wav"), volume, ATTN_NORM, 0);
  372.         break;
  373.  
  374. // ======================
  375. // PGM
  376.     case MZ_ETF_RIFLE:
  377.         dl->color[0] = 0.9;dl->color[1] = 0.7;dl->color[2] = 0;
  378.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/nail1.wav"), volume, ATTN_NORM, 0);
  379.         break;
  380.     case MZ_SHOTGUN2:
  381.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  382.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotg2.wav"), volume, ATTN_NORM, 0);
  383.         break;
  384.     case MZ_HEATBEAM:
  385.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  386.         dl->die = cl.time + 100;
  387. //        S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0);
  388.         break;
  389.     case MZ_BLASTER2:
  390.         dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
  391.         // FIXME - different sound for blaster2 ??
  392.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
  393.         break;
  394.     case MZ_TRACKER:
  395.         // negative flashes handled the same in gl/soft until CL_AddDLights
  396.         dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1;
  397.         S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/disint2.wav"), volume, ATTN_NORM, 0);
  398.         break;        
  399.     case MZ_NUKE1:
  400.         dl->color[0] = 1;dl->color[1] = 0;dl->color[2] = 0;
  401.         dl->die = cl.time + 100;
  402.         break;
  403.     case MZ_NUKE2:
  404.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  405.         dl->die = cl.time + 100;
  406.         break;
  407.     case MZ_NUKE4:
  408.         dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1;
  409.         dl->die = cl.time + 100;
  410.         break;
  411.     case MZ_NUKE8:
  412.         dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 1;
  413.         dl->die = cl.time + 100;
  414.         break;
  415. // PGM
  416. // ======================
  417.     }
  418. }
  419.  
  420.  
  421. /*
  422. ==============
  423. CL_ParseMuzzleFlash2
  424. ==============
  425. */
  426. void CL_ParseMuzzleFlash2 (void) 
  427. {
  428.     int            ent;
  429.     vec3_t        origin;
  430.     int            flash_number;
  431.     cdlight_t    *dl;
  432.     vec3_t        forward, right;
  433.     char        soundname[64];
  434.  
  435.     ent = MSG_ReadShort (&net_message);
  436.     if (ent < 1 || ent >= MAX_EDICTS)
  437.         Com_Error (ERR_DROP, "CL_ParseMuzzleFlash2: bad entity");
  438.  
  439.     flash_number = MSG_ReadByte (&net_message);
  440.  
  441.     // locate the origin
  442.     AngleVectors (cl_entities[ent].current.angles, forward, right, NULL);
  443.     origin[0] = cl_entities[ent].current.origin[0] + forward[0] * monster_flash_offset[flash_number][0] + right[0] * monster_flash_offset[flash_number][1];
  444.     origin[1] = cl_entities[ent].current.origin[1] + forward[1] * monster_flash_offset[flash_number][0] + right[1] * monster_flash_offset[flash_number][1];
  445.     origin[2] = cl_entities[ent].current.origin[2] + forward[2] * monster_flash_offset[flash_number][0] + right[2] * monster_flash_offset[flash_number][1] + monster_flash_offset[flash_number][2];
  446.  
  447.     dl = CL_AllocDlight (ent);
  448.     VectorCopy (origin,  dl->origin);
  449.     dl->radius = 200 + (rand()&31);
  450.     dl->minlight = 32;
  451.     dl->die = cl.time;    // + 0.1;
  452.  
  453.     switch (flash_number)
  454.     {
  455.     case MZ2_INFANTRY_MACHINEGUN_1:
  456.     case MZ2_INFANTRY_MACHINEGUN_2:
  457.     case MZ2_INFANTRY_MACHINEGUN_3:
  458.     case MZ2_INFANTRY_MACHINEGUN_4:
  459.     case MZ2_INFANTRY_MACHINEGUN_5:
  460.     case MZ2_INFANTRY_MACHINEGUN_6:
  461.     case MZ2_INFANTRY_MACHINEGUN_7:
  462.     case MZ2_INFANTRY_MACHINEGUN_8:
  463.     case MZ2_INFANTRY_MACHINEGUN_9:
  464.     case MZ2_INFANTRY_MACHINEGUN_10:
  465.     case MZ2_INFANTRY_MACHINEGUN_11:
  466.     case MZ2_INFANTRY_MACHINEGUN_12:
  467.     case MZ2_INFANTRY_MACHINEGUN_13:
  468.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  469.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  470.         CL_SmokeAndFlash(origin);
  471.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0);
  472.         break;
  473.  
  474.     case MZ2_SOLDIER_MACHINEGUN_1:
  475.     case MZ2_SOLDIER_MACHINEGUN_2:
  476.     case MZ2_SOLDIER_MACHINEGUN_3:
  477.     case MZ2_SOLDIER_MACHINEGUN_4:
  478.     case MZ2_SOLDIER_MACHINEGUN_5:
  479.     case MZ2_SOLDIER_MACHINEGUN_6:
  480.     case MZ2_SOLDIER_MACHINEGUN_7:
  481.     case MZ2_SOLDIER_MACHINEGUN_8:
  482.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  483.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  484.         CL_SmokeAndFlash(origin);
  485.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck3.wav"), 1, ATTN_NORM, 0);
  486.         break;
  487.  
  488.     case MZ2_GUNNER_MACHINEGUN_1:
  489.     case MZ2_GUNNER_MACHINEGUN_2:
  490.     case MZ2_GUNNER_MACHINEGUN_3:
  491.     case MZ2_GUNNER_MACHINEGUN_4:
  492.     case MZ2_GUNNER_MACHINEGUN_5:
  493.     case MZ2_GUNNER_MACHINEGUN_6:
  494.     case MZ2_GUNNER_MACHINEGUN_7:
  495.     case MZ2_GUNNER_MACHINEGUN_8:
  496.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  497.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  498.         CL_SmokeAndFlash(origin);
  499.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("gunner/gunatck2.wav"), 1, ATTN_NORM, 0);
  500.         break;
  501.  
  502.     case MZ2_ACTOR_MACHINEGUN_1:
  503.     case MZ2_SUPERTANK_MACHINEGUN_1:
  504.     case MZ2_SUPERTANK_MACHINEGUN_2:
  505.     case MZ2_SUPERTANK_MACHINEGUN_3:
  506.     case MZ2_SUPERTANK_MACHINEGUN_4:
  507.     case MZ2_SUPERTANK_MACHINEGUN_5:
  508.     case MZ2_SUPERTANK_MACHINEGUN_6:
  509.     case MZ2_TURRET_MACHINEGUN:            // PGM
  510.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  511.  
  512.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  513.         CL_SmokeAndFlash(origin);
  514.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0);
  515.         break;
  516.  
  517.     case MZ2_BOSS2_MACHINEGUN_L1:
  518.     case MZ2_BOSS2_MACHINEGUN_L2:
  519.     case MZ2_BOSS2_MACHINEGUN_L3:
  520.     case MZ2_BOSS2_MACHINEGUN_L4:
  521.     case MZ2_BOSS2_MACHINEGUN_L5:
  522.     case MZ2_CARRIER_MACHINEGUN_L1:        // PMM
  523.     case MZ2_CARRIER_MACHINEGUN_L2:        // PMM
  524.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  525.  
  526.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  527.         CL_SmokeAndFlash(origin);
  528.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NONE, 0);
  529.         break;
  530.  
  531.     case MZ2_SOLDIER_BLASTER_1:
  532.     case MZ2_SOLDIER_BLASTER_2:
  533.     case MZ2_SOLDIER_BLASTER_3:
  534.     case MZ2_SOLDIER_BLASTER_4:
  535.     case MZ2_SOLDIER_BLASTER_5:
  536.     case MZ2_SOLDIER_BLASTER_6:
  537.     case MZ2_SOLDIER_BLASTER_7:
  538.     case MZ2_SOLDIER_BLASTER_8:
  539.     case MZ2_TURRET_BLASTER:            // PGM
  540.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  541.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck2.wav"), 1, ATTN_NORM, 0);
  542.         break;
  543.  
  544.     case MZ2_FLYER_BLASTER_1:
  545.     case MZ2_FLYER_BLASTER_2:
  546.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  547.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("flyer/flyatck3.wav"), 1, ATTN_NORM, 0);
  548.         break;
  549.  
  550.     case MZ2_MEDIC_BLASTER_1:
  551.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  552.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("medic/medatck1.wav"), 1, ATTN_NORM, 0);
  553.         break;
  554.  
  555.     case MZ2_HOVER_BLASTER_1:
  556.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  557.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("hover/hovatck1.wav"), 1, ATTN_NORM, 0);
  558.         break;
  559.  
  560.     case MZ2_FLOAT_BLASTER_1:
  561.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  562.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("floater/fltatck1.wav"), 1, ATTN_NORM, 0);
  563.         break;
  564.  
  565.     case MZ2_SOLDIER_SHOTGUN_1:
  566.     case MZ2_SOLDIER_SHOTGUN_2:
  567.     case MZ2_SOLDIER_SHOTGUN_3:
  568.     case MZ2_SOLDIER_SHOTGUN_4:
  569.     case MZ2_SOLDIER_SHOTGUN_5:
  570.     case MZ2_SOLDIER_SHOTGUN_6:
  571.     case MZ2_SOLDIER_SHOTGUN_7:
  572.     case MZ2_SOLDIER_SHOTGUN_8:
  573.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  574.         CL_SmokeAndFlash(origin);
  575.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck1.wav"), 1, ATTN_NORM, 0);
  576.         break;
  577.  
  578.     case MZ2_TANK_BLASTER_1:
  579.     case MZ2_TANK_BLASTER_2:
  580.     case MZ2_TANK_BLASTER_3:
  581.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  582.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0);
  583.         break;
  584.  
  585.     case MZ2_TANK_MACHINEGUN_1:
  586.     case MZ2_TANK_MACHINEGUN_2:
  587.     case MZ2_TANK_MACHINEGUN_3:
  588.     case MZ2_TANK_MACHINEGUN_4:
  589.     case MZ2_TANK_MACHINEGUN_5:
  590.     case MZ2_TANK_MACHINEGUN_6:
  591.     case MZ2_TANK_MACHINEGUN_7:
  592.     case MZ2_TANK_MACHINEGUN_8:
  593.     case MZ2_TANK_MACHINEGUN_9:
  594.     case MZ2_TANK_MACHINEGUN_10:
  595.     case MZ2_TANK_MACHINEGUN_11:
  596.     case MZ2_TANK_MACHINEGUN_12:
  597.     case MZ2_TANK_MACHINEGUN_13:
  598.     case MZ2_TANK_MACHINEGUN_14:
  599.     case MZ2_TANK_MACHINEGUN_15:
  600.     case MZ2_TANK_MACHINEGUN_16:
  601.     case MZ2_TANK_MACHINEGUN_17:
  602.     case MZ2_TANK_MACHINEGUN_18:
  603.     case MZ2_TANK_MACHINEGUN_19:
  604.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  605.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  606.         CL_SmokeAndFlash(origin);
  607.         Com_sprintf(soundname, sizeof(soundname), "tank/tnkatk2%c.wav", 'a' + rand() % 5);
  608.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound(soundname), 1, ATTN_NORM, 0);
  609.         break;
  610.  
  611.     case MZ2_CHICK_ROCKET_1:
  612.     case MZ2_TURRET_ROCKET:            // PGM
  613.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
  614.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("chick/chkatck2.wav"), 1, ATTN_NORM, 0);
  615.         break;
  616.  
  617.     case MZ2_TANK_ROCKET_1:
  618.     case MZ2_TANK_ROCKET_2:
  619.     case MZ2_TANK_ROCKET_3:
  620.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
  621.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck1.wav"), 1, ATTN_NORM, 0);
  622.         break;
  623.  
  624.     case MZ2_SUPERTANK_ROCKET_1:
  625.     case MZ2_SUPERTANK_ROCKET_2:
  626.     case MZ2_SUPERTANK_ROCKET_3:
  627.     case MZ2_BOSS2_ROCKET_1:
  628.     case MZ2_BOSS2_ROCKET_2:
  629.     case MZ2_BOSS2_ROCKET_3:
  630.     case MZ2_BOSS2_ROCKET_4:
  631.     case MZ2_CARRIER_ROCKET_1:
  632. //    case MZ2_CARRIER_ROCKET_2:
  633. //    case MZ2_CARRIER_ROCKET_3:
  634. //    case MZ2_CARRIER_ROCKET_4:
  635.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
  636.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/rocket.wav"), 1, ATTN_NORM, 0);
  637.         break;
  638.  
  639.     case MZ2_GUNNER_GRENADE_1:
  640.     case MZ2_GUNNER_GRENADE_2:
  641.     case MZ2_GUNNER_GRENADE_3:
  642.     case MZ2_GUNNER_GRENADE_4:
  643.         dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
  644.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("gunner/gunatck3.wav"), 1, ATTN_NORM, 0);
  645.         break;
  646.  
  647.     case MZ2_GLADIATOR_RAILGUN_1:
  648.     // PMM
  649.     case MZ2_CARRIER_RAILGUN:
  650.     case MZ2_WIDOW_RAIL:
  651.     // pmm
  652.         dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0;
  653.         break;
  654.  
  655. // --- Xian's shit starts ---
  656.     case MZ2_MAKRON_BFG:
  657.         dl->color[0] = 0.5;dl->color[1] = 1 ;dl->color[2] = 0.5;
  658.         //S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("makron/bfg_fire.wav"), 1, ATTN_NORM, 0);
  659.         break;
  660.  
  661.     case MZ2_MAKRON_BLASTER_1:
  662.     case MZ2_MAKRON_BLASTER_2:
  663.     case MZ2_MAKRON_BLASTER_3:
  664.     case MZ2_MAKRON_BLASTER_4:
  665.     case MZ2_MAKRON_BLASTER_5:
  666.     case MZ2_MAKRON_BLASTER_6:
  667.     case MZ2_MAKRON_BLASTER_7:
  668.     case MZ2_MAKRON_BLASTER_8:
  669.     case MZ2_MAKRON_BLASTER_9:
  670.     case MZ2_MAKRON_BLASTER_10:
  671.     case MZ2_MAKRON_BLASTER_11:
  672.     case MZ2_MAKRON_BLASTER_12:
  673.     case MZ2_MAKRON_BLASTER_13:
  674.     case MZ2_MAKRON_BLASTER_14:
  675.     case MZ2_MAKRON_BLASTER_15:
  676.     case MZ2_MAKRON_BLASTER_16:
  677.     case MZ2_MAKRON_BLASTER_17:
  678.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  679.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("makron/blaster.wav"), 1, ATTN_NORM, 0);
  680.         break;
  681.     
  682.     case MZ2_JORG_MACHINEGUN_L1:
  683.     case MZ2_JORG_MACHINEGUN_L2:
  684.     case MZ2_JORG_MACHINEGUN_L3:
  685.     case MZ2_JORG_MACHINEGUN_L4:
  686.     case MZ2_JORG_MACHINEGUN_L5:
  687.     case MZ2_JORG_MACHINEGUN_L6:
  688.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  689.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  690.         CL_SmokeAndFlash(origin);
  691.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("boss3/xfire.wav"), 1, ATTN_NORM, 0);
  692.         break;
  693.  
  694.     case MZ2_JORG_MACHINEGUN_R1:
  695.     case MZ2_JORG_MACHINEGUN_R2:
  696.     case MZ2_JORG_MACHINEGUN_R3:
  697.     case MZ2_JORG_MACHINEGUN_R4:
  698.     case MZ2_JORG_MACHINEGUN_R5:
  699.     case MZ2_JORG_MACHINEGUN_R6:
  700.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  701.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  702.         CL_SmokeAndFlash(origin);
  703.         break;
  704.  
  705.     case MZ2_JORG_BFG_1:
  706.         dl->color[0] = 0.5;dl->color[1] = 1 ;dl->color[2] = 0.5;
  707.         break;
  708.  
  709.     case MZ2_BOSS2_MACHINEGUN_R1:
  710.     case MZ2_BOSS2_MACHINEGUN_R2:
  711.     case MZ2_BOSS2_MACHINEGUN_R3:
  712.     case MZ2_BOSS2_MACHINEGUN_R4:
  713.     case MZ2_BOSS2_MACHINEGUN_R5:
  714.     case MZ2_CARRIER_MACHINEGUN_R1:            // PMM
  715.     case MZ2_CARRIER_MACHINEGUN_R2:            // PMM
  716.  
  717.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  718.  
  719.         CL_ParticleEffect (origin, vec3_origin, 0, 40);
  720.         CL_SmokeAndFlash(origin);
  721.         break;
  722.  
  723. // ======
  724. // ROGUE
  725.     case MZ2_STALKER_BLASTER:
  726.     case MZ2_DAEDALUS_BLASTER:
  727.     case MZ2_MEDIC_BLASTER_2:
  728.     case MZ2_WIDOW_BLASTER:
  729.     case MZ2_WIDOW_BLASTER_SWEEP1:
  730.     case MZ2_WIDOW_BLASTER_SWEEP2:
  731.     case MZ2_WIDOW_BLASTER_SWEEP3:
  732.     case MZ2_WIDOW_BLASTER_SWEEP4:
  733.     case MZ2_WIDOW_BLASTER_SWEEP5:
  734.     case MZ2_WIDOW_BLASTER_SWEEP6:
  735.     case MZ2_WIDOW_BLASTER_SWEEP7:
  736.     case MZ2_WIDOW_BLASTER_SWEEP8:
  737.     case MZ2_WIDOW_BLASTER_SWEEP9:
  738.     case MZ2_WIDOW_BLASTER_100:
  739.     case MZ2_WIDOW_BLASTER_90:
  740.     case MZ2_WIDOW_BLASTER_80:
  741.     case MZ2_WIDOW_BLASTER_70:
  742.     case MZ2_WIDOW_BLASTER_60:
  743.     case MZ2_WIDOW_BLASTER_50:
  744.     case MZ2_WIDOW_BLASTER_40:
  745.     case MZ2_WIDOW_BLASTER_30:
  746.     case MZ2_WIDOW_BLASTER_20:
  747.     case MZ2_WIDOW_BLASTER_10:
  748.     case MZ2_WIDOW_BLASTER_0:
  749.     case MZ2_WIDOW_BLASTER_10L:
  750.     case MZ2_WIDOW_BLASTER_20L:
  751.     case MZ2_WIDOW_BLASTER_30L:
  752.     case MZ2_WIDOW_BLASTER_40L:
  753.     case MZ2_WIDOW_BLASTER_50L:
  754.     case MZ2_WIDOW_BLASTER_60L:
  755.     case MZ2_WIDOW_BLASTER_70L:
  756.     case MZ2_WIDOW_RUN_1:
  757.     case MZ2_WIDOW_RUN_2:
  758.     case MZ2_WIDOW_RUN_3:
  759.     case MZ2_WIDOW_RUN_4:
  760.     case MZ2_WIDOW_RUN_5:
  761.     case MZ2_WIDOW_RUN_6:
  762.     case MZ2_WIDOW_RUN_7:
  763.     case MZ2_WIDOW_RUN_8:
  764.         dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
  765.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0);
  766.         break;
  767.  
  768.     case MZ2_WIDOW_DISRUPTOR:
  769.         dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1;
  770.         S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("weapons/disint2.wav"), 1, ATTN_NORM, 0);
  771.         break;
  772.  
  773.     case MZ2_WIDOW_PLASMABEAM:
  774.     case MZ2_WIDOW2_BEAMER_1:
  775.     case MZ2_WIDOW2_BEAMER_2:
  776.     case MZ2_WIDOW2_BEAMER_3:
  777.     case MZ2_WIDOW2_BEAMER_4:
  778.     case MZ2_WIDOW2_BEAMER_5:
  779.     case MZ2_WIDOW2_BEAM_SWEEP_1:
  780.     case MZ2_WIDOW2_BEAM_SWEEP_2:
  781.     case MZ2_WIDOW2_BEAM_SWEEP_3:
  782.     case MZ2_WIDOW2_BEAM_SWEEP_4:
  783.     case MZ2_WIDOW2_BEAM_SWEEP_5:
  784.     case MZ2_WIDOW2_BEAM_SWEEP_6:
  785.     case MZ2_WIDOW2_BEAM_SWEEP_7:
  786.     case MZ2_WIDOW2_BEAM_SWEEP_8:
  787.     case MZ2_WIDOW2_BEAM_SWEEP_9:
  788.     case MZ2_WIDOW2_BEAM_SWEEP_10:
  789.     case MZ2_WIDOW2_BEAM_SWEEP_11:
  790.         dl->radius = 300 + (rand()&100);
  791.         dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
  792.         dl->die = cl.time + 200;
  793.         break;
  794. // ROGUE
  795. // ======
  796.  
  797. // --- Xian's shit ends ---
  798.  
  799.     }
  800. }
  801.  
  802.  
  803. /*
  804. ===============
  805. CL_AddDLights
  806.  
  807. ===============
  808. */
  809. void CL_AddDLights (void)
  810. {
  811.     int            i;
  812.     cdlight_t    *dl;
  813.  
  814.     dl = cl_dlights;
  815.  
  816. //=====
  817. //PGM
  818.     for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
  819.     {
  820.         if (!dl->radius)
  821.             continue;
  822.         V_AddLight (dl->origin, dl->radius,
  823.             dl->color[0], dl->color[1], dl->color[2]);
  824.     }
  825. //PGM
  826. //=====
  827. }
  828.  
  829.  
  830.  
  831. /*
  832. ==============================================================
  833.  
  834. PARTICLE MANAGEMENT
  835.  
  836. ==============================================================
  837. */
  838.  
  839. /*
  840. // THIS HAS BEEN RELOCATED TO CLIENT.H
  841. typedef struct particle_s
  842. {
  843.     struct particle_s    *next;
  844.  
  845.     float        time;
  846.  
  847.     vec3_t        org;
  848.     vec3_t        vel;
  849.     vec3_t        accel;
  850.     float        color;
  851.     float        colorvel;
  852.     float        alpha;
  853.     float        alphavel;
  854. } cparticle_t;
  855.  
  856.  
  857. #define    PARTICLE_GRAVITY    40
  858. */
  859.  
  860. cparticle_t    *active_particles, *free_particles;
  861.  
  862. cparticle_t    particles[MAX_PARTICLES];
  863. int            cl_numparticles = MAX_PARTICLES;
  864.  
  865.  
  866. /*
  867. ===============
  868. CL_ClearParticles
  869. ===============
  870. */
  871. void CL_ClearParticles (void)
  872. {
  873.     int        i;
  874.     
  875.     free_particles = &particles[0];
  876.     active_particles = NULL;
  877.  
  878.     for (i=0 ;i<cl_numparticles ; i++)
  879.         particles[i].next = &particles[i+1];
  880.     particles[cl_numparticles-1].next = NULL;
  881. }
  882.  
  883. #ifdef _WIN32
  884. static __inline cparticle_t *new_particle (void)
  885. #else
  886. static inline cparticle_t *new_particle (void)
  887. #endif
  888. {
  889.     cparticle_t    *p;
  890.  
  891.     if (!free_particles)
  892.         return NULL;
  893.  
  894.     p = free_particles;
  895.     free_particles = p->next;
  896.     p->next = active_particles;
  897.     p->type = 0;
  898.     p->time = cl.time;
  899.  
  900.     return (active_particles = p);
  901. }
  902.  
  903. /*
  904. ===============
  905. CL_ParticleEffect
  906.  
  907. Wall impact puffs
  908. ===============
  909. */
  910. void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count)
  911. {
  912.     int            i, j;
  913.     cparticle_t    *p;
  914.     float        d;
  915.  
  916.     for (i=0 ; i<count ; i++)
  917.     {
  918.         if (!(p = new_particle()))
  919.             return;
  920.  
  921.         d = rand()&31;
  922.         for (j=0 ; j<3 ; j++)
  923.         {
  924.             p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
  925.             p->vel[j] = crand()*20;
  926.         }
  927.  
  928.         p->accel[0] = p->accel[1] = 0;
  929.         p->accel[2] = -PARTICLE_GRAVITY;
  930.  
  931.         if (color == 425)        // gunshots: FIXME should be using type
  932.         {
  933.             p->type = PARTICLE_GUNSHOT;// + (rand()&7);
  934.             p->alpha = 0.8;
  935.         }
  936.         else if (color == 450)
  937.         {
  938.             p->type = PARTICLE_BLOOD;
  939.             p->alpha = 1.0;
  940.         }
  941.         else if (color == 550)
  942.         {
  943.             p->type = PARTICLE_GREEN_BLOOD;
  944.             p->alpha = 1.0;
  945.         }
  946.         else
  947.         {
  948.             p->alpha = 1.0;
  949.             p->color = color;
  950.         }
  951.  
  952.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  953.     }
  954. }
  955.  
  956.  
  957. /*
  958. ===============
  959. CL_ParticleEffect2
  960. ===============
  961. */
  962. void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count)
  963. {
  964.     int            i, j;
  965.     cparticle_t    *p;
  966.     float        d;
  967.  
  968.     for (i=0 ; i<count ; i++)
  969.     {
  970.         if (!(p = new_particle()))
  971.             return;
  972.  
  973.         p->color = color;
  974.  
  975.         d = rand()&7;
  976.         for (j=0 ; j<3 ; j++)
  977.         {
  978.             p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
  979.             p->vel[j] = crand()*20;
  980.         }
  981.  
  982.         p->accel[0] = p->accel[1] = 0;
  983.         p->accel[2] = -PARTICLE_GRAVITY;
  984.         p->alpha = 1.0;
  985.  
  986.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  987.     }
  988. }
  989.  
  990.  
  991. // RAFAEL
  992. /*
  993. ===============
  994. CL_ParticleEffect3
  995. ===============
  996. */
  997. void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count)
  998. {
  999.     int            i, j;
  1000.     cparticle_t    *p;
  1001.     float        d;
  1002.  
  1003.     for (i=0 ; i<count ; i++)
  1004.     {
  1005.         if (!(p = new_particle()))
  1006.             return;
  1007.  
  1008.         p->color = color;
  1009.  
  1010.         d = rand()&7;
  1011.         for (j=0 ; j<3 ; j++)
  1012.         {
  1013.             p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
  1014.             p->vel[j] = crand()*20;
  1015.         }
  1016.  
  1017.         p->accel[0] = p->accel[1] = 0;
  1018.         p->accel[2] = PARTICLE_GRAVITY;
  1019.         p->alpha = 1.0;
  1020.  
  1021.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  1022.     }
  1023. }
  1024.  
  1025. /*
  1026. ===============
  1027. CL_TeleporterParticles
  1028. ===============
  1029. */
  1030. void CL_TeleporterParticles (entity_state_t *ent)
  1031. {
  1032.     int            i, j;
  1033.     cparticle_t    *p;
  1034.  
  1035.     for (i=0 ; i<8 ; i++)
  1036.     {
  1037.         if (!(p = new_particle()))
  1038.             return;
  1039.  
  1040.         p->color = 0xdb;
  1041.  
  1042.         for (j=0 ; j<2 ; j++)
  1043.         {
  1044.             p->org[j] = ent->origin[j] - 16 + (rand()&31);
  1045.             p->vel[j] = crand()*14;
  1046.         }
  1047.  
  1048.         p->org[2] = ent->origin[2] - 8 + (rand()&7);
  1049.         p->vel[2] = 80 + (rand()&7);
  1050.  
  1051.         p->accel[0] = p->accel[1] = 0;
  1052.         p->accel[2] = -PARTICLE_GRAVITY;
  1053.         p->alpha = 1.0;
  1054.  
  1055.         p->alphavel = -0.5;
  1056.     }
  1057. }
  1058.  
  1059.  
  1060. /*
  1061. ===============
  1062. CL_LogoutEffect
  1063.  
  1064. ===============
  1065. */
  1066. void CL_LogoutEffect (vec3_t org, int type)
  1067. {
  1068.     int            i, j;
  1069.     cparticle_t    *p;
  1070.  
  1071.     for (i=0 ; i<500 ; i++)
  1072.     {
  1073.         if (!(p = new_particle()))
  1074.             return;
  1075.  
  1076.         if (type == MZ_LOGIN)
  1077.             p->color = 0xd0 + (rand()&7);    // green
  1078.         else if (type == MZ_LOGOUT)
  1079.             p->color = 0x40 + (rand()&7);    // red
  1080.         else
  1081.             p->color = 0xe0 + (rand()&7);    // yellow
  1082.  
  1083.         p->org[0] = org[0] - 16 + frand()*32;
  1084.         p->org[1] = org[1] - 16 + frand()*32;
  1085.         p->org[2] = org[2] - 24 + frand()*56;
  1086.  
  1087.         for (j=0 ; j<3 ; j++)
  1088.             p->vel[j] = crand()*20;
  1089.  
  1090.         p->accel[0] = p->accel[1] = 0;
  1091.         p->accel[2] = -PARTICLE_GRAVITY;
  1092.         p->alpha = 1.0;
  1093.  
  1094.         p->alphavel = -1.0 / (1.0 + frand()*0.3);
  1095.     }
  1096. }
  1097.  
  1098.  
  1099. /*
  1100. ===============
  1101. CL_ItemRespawnParticles
  1102.  
  1103. ===============
  1104. */
  1105. void CL_ItemRespawnParticles (vec3_t org)
  1106. {
  1107.     int            i, j;
  1108.     cparticle_t    *p;
  1109.  
  1110.     for (i=0 ; i<64 ; i++)
  1111.     {
  1112.         if (!(p = new_particle()))
  1113.             return;
  1114.  
  1115.         p->color = 0xd4 + (rand()&3);    // green
  1116.  
  1117.         p->org[0] = org[0] + crand()*8;
  1118.         p->org[1] = org[1] + crand()*8;
  1119.         p->org[2] = org[2] + crand()*8;
  1120.  
  1121.         for (j=0 ; j<3 ; j++)
  1122.             p->vel[j] = crand()*8;
  1123.  
  1124.         p->accel[0] = p->accel[1] = 0;
  1125.         p->accel[2] = -PARTICLE_GRAVITY*0.2;
  1126.         p->alpha = 1.0;
  1127.  
  1128.         p->alphavel = -1.0 / (1.0 + frand()*0.3);
  1129.     }
  1130. }
  1131.  
  1132.  
  1133. /*
  1134. ===============
  1135. CL_ExplosionParticles
  1136. ===============
  1137. */
  1138. void CL_ExplosionParticles (vec3_t org)
  1139. {
  1140.     int            i, j;
  1141.     cparticle_t    *p;
  1142.  
  1143.     for (i=0 ; i<256 ; i++)
  1144.     {
  1145.         if (!(p = new_particle()))
  1146.             return;
  1147.  
  1148.         p->type = PARTICLE_EXPLOSION;
  1149.         for (j=0 ; j<3 ; j++)
  1150.         {
  1151.         //    p->org[j] = org[j] + ((rand()%32)-16);
  1152.         //    p->vel[j] = (rand()%384)-192;
  1153.             p->org[j] = org[j] + ((rand()%4)-2);
  1154.             p->vel[j] = (rand()%328)-164;
  1155.         }
  1156.  
  1157.         p->accel[0] = p->accel[1] = 0;
  1158.         p->accel[2] = -PARTICLE_GRAVITY;
  1159.         p->alpha = 0.9;
  1160.  
  1161.         p->alphavel = -0.8 / (0.5 + frand()*0.3);
  1162.     }
  1163. }
  1164.  
  1165. /*
  1166. ===============
  1167. CL_MuzzleParticles
  1168. ===============
  1169. */
  1170. void CL_MuzzleParticles (vec3_t org)
  1171. {
  1172.     int            i, j;
  1173.     cparticle_t    *p;
  1174.  
  1175.     for ( i = 0; i < 4; i++)
  1176.     {
  1177.         if (!(p = new_particle()))
  1178.             return;
  1179.  
  1180.         p->type = PARTICLE_BLASTER_MZFLASH;
  1181.         for (j=0 ; j<3 ; j++)
  1182.         {
  1183.             p->org[j] = org[j] + ((rand()%2)-1);
  1184.             p->vel[j] = 0;
  1185.         }
  1186.         p->accel[0] = p->accel[1] = 0;
  1187.         p->accel[2] = 0;
  1188.         p->alpha = 0.8;
  1189.  
  1190.         p->alphavel = -2.8 / (0.5 + frand()*0.3);
  1191.     }
  1192.     
  1193. }
  1194.  
  1195. /*
  1196. ===============
  1197. CL_Leaderfield
  1198. ===============
  1199. */
  1200. void CL_Leaderfield (vec3_t org)
  1201. {
  1202.     int            i, j;
  1203.     cparticle_t    *p;
  1204.  
  1205.     for ( i = 0; i < 3; i++)
  1206.     {
  1207.         if (!(p = new_particle()))
  1208.             return;
  1209.  
  1210.         p->type = PARTICLE_LEADER_FIELD;
  1211.         for (j=0 ; j<3 ; j++)
  1212.         {
  1213.             p->org[j] = org[j] + ((rand()%2)-1);
  1214.             p->vel[j] = 0;
  1215.         }
  1216.         p->accel[0] = p->accel[1] = 0;
  1217.         p->accel[2] = 0;
  1218.         p->alpha = 0.7;
  1219.  
  1220.         p->alphavel = -2.8 / (0.5 + frand()*0.3);
  1221.     }
  1222.     
  1223. }
  1224.  
  1225. /*
  1226. ===============
  1227. CL_DustParticles
  1228. ===============
  1229. */
  1230. void CL_DustParticles (vec3_t org)
  1231. {
  1232.     int            i, j;
  1233.     cparticle_t    *p;
  1234.  
  1235.     for (i=0 ; i<64 ; i++)
  1236.     {
  1237.         if (!(p = new_particle()))
  1238.             return;
  1239.  
  1240.         p->type = PARTICLE_GUNSHOT;
  1241.         for (j=0 ; j<3 ; j++)
  1242.         {
  1243.         //    p->org[j] = org[j] + ((rand()%32)-16);
  1244.         //    p->vel[j] = (rand()%384)-192;
  1245.             p->org[j] = org[j] + ((rand()%4)-2);
  1246.             p->vel[j] = (rand()%88)-44;
  1247.         }
  1248.  
  1249.         p->accel[0] = p->accel[1] = 0;
  1250.         p->accel[2] = -PARTICLE_GRAVITY;
  1251.         p->alpha = 0.5;
  1252.  
  1253.         p->alphavel = -0.8 / (0.5 + frand()*0.3);
  1254.     }
  1255. }
  1256.  
  1257. /*
  1258. ===============
  1259. CL_BigTeleportParticles
  1260. ===============
  1261. */
  1262. void CL_BigTeleportParticles (vec3_t org)
  1263. {
  1264.     int            i;
  1265.     cparticle_t    *p;
  1266.     float        angle, dist;
  1267.     static int colortable[4] = {2*8,13*8,21*8,18*8};
  1268.  
  1269.     for (i=0 ; i<128 ; i++)
  1270.     {
  1271.         if (!(p = new_particle()))
  1272.             return;
  1273.  
  1274.         p->type = PARTICLE_BLASTER_MZFLASH;//colortable[rand()&3];
  1275.  
  1276.         angle = M_PI*2*(rand()&1023)/1023.0;
  1277.         dist = rand()&11;
  1278.         p->org[0] = org[0] + cos(angle)*dist;
  1279.         p->vel[0] = cos(angle)*(20+(rand()&23));
  1280.         p->accel[0] = -cos(angle)*30;
  1281.  
  1282.         p->org[1] = org[1] + sin(angle)*dist;
  1283.         p->vel[1] = sin(angle)*(20+(rand()&23));
  1284.         p->accel[1] = -sin(angle)*100;
  1285.  
  1286.         p->org[2] = org[2] + 8 + (rand()%40);
  1287.         p->vel[2] = -100 + (rand()&31);
  1288.         p->accel[2] = PARTICLE_GRAVITY*24;
  1289.         p->alpha = 0.5;
  1290.  
  1291.         p->alphavel = -0.6 / (0.5 + frand()*0.3);
  1292.     }
  1293. }
  1294.  
  1295.  
  1296. /*
  1297. ===============
  1298. CL_BlasterParticles
  1299.  
  1300. Wall impact puffs
  1301. ===============
  1302. */
  1303. void CL_BlasterParticles (vec3_t org, vec3_t dir)
  1304. {
  1305.     int            i, j;
  1306.     cparticle_t    *p;
  1307.     float        d;
  1308.     int            count;
  1309.  
  1310.     count = 50;
  1311.     for (i=0 ; i<count ; i++)
  1312.     {
  1313.         if (!(p = new_particle()))
  1314.             return;
  1315.  
  1316.         p->type = PARTICLE_BLASTER;
  1317.  
  1318.         d = rand()&15;
  1319.         for (j=0 ; j<3 ; j++)
  1320.         {
  1321.             p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
  1322.             p->vel[j] = dir[j] * 30 + crand()*40;
  1323.         }
  1324.  
  1325.         p->accel[0] = p->accel[1] = 0;
  1326.         p->accel[2] = -PARTICLE_GRAVITY;
  1327.         p->alpha = 0.8;
  1328.  
  1329.         p->alphavel = -1.0 / (0.5 + frand()*0.3);
  1330.     }
  1331. }
  1332.  
  1333.  
  1334. /*
  1335. ===============
  1336. CL_BlasterTrail
  1337.  
  1338. ===============
  1339. */
  1340. void CL_BlasterTrail (vec3_t start, vec3_t end)
  1341. {
  1342.     vec3_t        move;
  1343.     vec3_t        vec;
  1344.     float        len;
  1345.     int            j;
  1346.     cparticle_t    *p;
  1347.     int            dec;
  1348.  
  1349.     VectorCopy (start, move);
  1350.     VectorSubtract (end, start, vec);
  1351.     len = VectorNormalize (vec);
  1352.  
  1353.     dec = 5;
  1354.     VectorScale (vec, 5, vec);
  1355.  
  1356.     // FIXME: this is a really silly way to have a loop
  1357.     while (len > 0)
  1358.     {
  1359.         len -= dec;
  1360.  
  1361.         if (!(p = new_particle()))
  1362.             return;
  1363.  
  1364.         VectorClear (p->accel);
  1365.  
  1366.         p->alpha = 1.0;
  1367.         p->alphavel = -1.0 / (0.3+frand()*0.2);
  1368.         p->color = 0xe0;
  1369.         for (j=0 ; j<3 ; j++)
  1370.         {
  1371.             p->org[j] = move[j] + crand();
  1372.             p->vel[j] = crand()*5;
  1373.             p->accel[j] = 0;
  1374.         }
  1375.  
  1376.         VectorAdd (move, vec, move);
  1377.     }
  1378. }
  1379.  
  1380. /*
  1381. ===============
  1382. CL_QuadTrail
  1383.  
  1384. ===============
  1385. */
  1386. void CL_QuadTrail (vec3_t start, vec3_t end)
  1387. {
  1388.     vec3_t        move;
  1389.     vec3_t        vec;
  1390.     float        len;
  1391.     int            j;
  1392.     cparticle_t    *p;
  1393.     int            dec;
  1394.  
  1395.     VectorCopy (start, move);
  1396.     VectorSubtract (end, start, vec);
  1397.     len = VectorNormalize (vec);
  1398.  
  1399.     dec = 5;
  1400.     VectorScale (vec, 5, vec);
  1401.  
  1402.     while (len > 0)
  1403.     {
  1404.         len -= dec;
  1405.  
  1406.         if (!(p = new_particle()))
  1407.             return;
  1408.  
  1409.         VectorClear (p->accel);
  1410.  
  1411.         p->alpha = 1.0;
  1412.         p->alphavel = -1.0 / (0.8+frand()*0.2);
  1413.         p->color = 115;
  1414.         for (j=0 ; j<3 ; j++)
  1415.         {
  1416.             p->org[j] = move[j] + crand()*16;
  1417.             p->vel[j] = crand()*5;
  1418.             p->accel[j] = 0;
  1419.         }
  1420.  
  1421.         VectorAdd (move, vec, move);
  1422.     }
  1423. }
  1424.  
  1425. /*
  1426. ===============
  1427. CL_FlagTrail
  1428.  
  1429. ===============
  1430. */
  1431. void CL_FlagTrail (vec3_t start, vec3_t end, float color)
  1432. {
  1433.     vec3_t        move;
  1434.     vec3_t        vec;
  1435.     float        len;
  1436.     int            j;
  1437.     cparticle_t    *p;
  1438.     int            dec;
  1439.  
  1440.     VectorCopy (start, move);
  1441.     VectorSubtract (end, start, vec);
  1442.     len = VectorNormalize (vec);
  1443.  
  1444.     dec = 5;
  1445.     VectorScale (vec, 5, vec);
  1446.  
  1447.     while (len > 0)
  1448.     {
  1449.         len -= dec;
  1450.  
  1451.         if (!(p = new_particle()))
  1452.             return;
  1453.  
  1454.         VectorClear (p->accel);
  1455.  
  1456.         p->alpha = 1.0;
  1457.         p->alphavel = -1.0 / (0.8+frand()*0.2);
  1458.         p->color = color;
  1459.         for (j=0 ; j<3 ; j++)
  1460.         {
  1461.             p->org[j] = move[j] + crand()*16;
  1462.             p->vel[j] = crand()*5;
  1463.             p->accel[j] = 0;
  1464.         }
  1465.  
  1466.         VectorAdd (move, vec, move);
  1467.     }
  1468. }
  1469.  
  1470. /*
  1471. ===============
  1472. CL_DiminishingTrail
  1473.  
  1474. ===============
  1475. */
  1476. void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags)
  1477. {
  1478.     vec3_t        move;
  1479.     vec3_t        vec;
  1480.     float        len;
  1481.     int            j;
  1482.     cparticle_t    *p;
  1483.     float        dec;
  1484.     float        orgscale;
  1485.     float        velscale;
  1486.  
  1487.     VectorCopy (start, move);
  1488.     VectorSubtract (end, start, vec);
  1489.     len = VectorNormalize (vec);
  1490.  
  1491.     dec = 0.5;
  1492.     VectorScale (vec, dec, vec);
  1493.  
  1494.     if (old->trailcount > 900)
  1495.     {
  1496.         orgscale = 4;
  1497.         velscale = 15;
  1498.     }
  1499.     else if (old->trailcount > 800)
  1500.     {
  1501.         orgscale = 2;
  1502.         velscale = 10;
  1503.     }
  1504.     else
  1505.     {
  1506.         orgscale = 1;
  1507.         velscale = 5;
  1508.     }
  1509.  
  1510.     // add stains if moving
  1511.     if ( len ) {
  1512.         if ( flags & EF_GIB ) {
  1513.             V_AddStain ( end, 25, 120, 0, 0, 200 );
  1514.         } else if ( flags & EF_GREENGIB ) {
  1515.             V_AddStain ( end, 25, 0, 100, 0, 200 );
  1516.         }
  1517.     }
  1518.     
  1519.     while (len > 0)
  1520.     {
  1521.         len -= dec;
  1522.  
  1523.         if (!free_particles)
  1524.             return;
  1525.  
  1526.         // drop less particles as it flies
  1527.         if ((rand()&1023) < old->trailcount)
  1528.         {
  1529.             if (!(p = new_particle()))
  1530.                 return;
  1531.  
  1532.             if (flags & EF_GIB)
  1533.             {
  1534.                 p->alpha = 1.0;
  1535.                 p->alphavel = -1.0 / (1+frand()*0.4);
  1536.                 p->type = PARTICLE_BLOOD;
  1537.                 for (j=0 ; j<3 ; j++)
  1538.                 {
  1539.                     p->org[j] = move[j] + crand()*orgscale;
  1540.                     p->vel[j] = crand()*velscale;
  1541.                     p->accel[j] = 0;
  1542.                 }
  1543.                 p->vel[2] -= PARTICLE_GRAVITY;
  1544.             }
  1545.             else if (flags & EF_GREENGIB)
  1546.             {
  1547.                 p->alpha = 1.0;
  1548.                 p->alphavel = -1.0 / (1+frand()*0.4);
  1549.                 p->type = PARTICLE_GREEN_BLOOD;
  1550.                 for (j=0; j< 3; j++)
  1551.                 {
  1552.                     p->org[j] = move[j] + crand()*orgscale;
  1553.                     p->vel[j] = crand()*velscale;
  1554.                     p->accel[j] = 0;
  1555.                 }
  1556.                 p->vel[2] -= PARTICLE_GRAVITY;
  1557.             }
  1558.             else if (flags & EF_SHIPEXHAUST)
  1559.             {
  1560.                 p->alpha = 0.8;
  1561.                 p->alphavel = -1.0 / (1+frand()*0.4);
  1562.                 p->type = PARTICLE_SMOKE;// + (rand()&7); 
  1563.                 for (j=0 ; j<3 ; j++)
  1564.                 {
  1565.                     p->org[j] = move[j] + crand()*orgscale;
  1566.                     p->vel[j] = crand()*velscale;
  1567.                 }
  1568.                 p->accel[2] = 20;
  1569.             }
  1570.             else
  1571.             {
  1572.                 p->alpha = 1.0;
  1573.                 p->alphavel = -1.0 / (1+frand()*0.2);
  1574.                 p->type = PARTICLE_SMOKE;// + (rand()&7); 
  1575.                 for (j=0 ; j<3 ; j++)
  1576.                 {
  1577.                     p->org[j] = move[j] + crand()*orgscale;
  1578.                     p->vel[j] = crand()*velscale;
  1579.                 }
  1580.                 p->accel[2] = 20;
  1581.             }
  1582.         }
  1583.  
  1584.         old->trailcount -= 5;
  1585.         if (old->trailcount < 100)
  1586.             old->trailcount = 100;
  1587.         VectorAdd (move, vec, move);
  1588.     }
  1589. }
  1590.  
  1591. void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up)
  1592. {
  1593.     float        d;
  1594.  
  1595.     // this rotate and negat guarantees a vector
  1596.     // not colinear with the original
  1597.     right[1] = -forward[0];
  1598.     right[2] = forward[1];
  1599.     right[0] = forward[2];
  1600.  
  1601.     d = DotProduct (right, forward);
  1602.     VectorMA (right, -d, forward, right);
  1603.     VectorNormalize (right);
  1604.     CrossProduct (right, forward, up);
  1605. }
  1606.  
  1607. /*
  1608. ===============
  1609. CL_RocketTrail
  1610.  
  1611. ===============
  1612. */
  1613. void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old)
  1614. {
  1615.     vec3_t        move;
  1616.     vec3_t        vec;
  1617.     float        len;
  1618.     int            j;
  1619.     cparticle_t    *p;
  1620.     float        dec;
  1621.  
  1622.     // smoke
  1623.     CL_DiminishingTrail (start, end, old, EF_ROCKET);
  1624.  
  1625.     // fire
  1626.     VectorCopy (start, move);
  1627.     VectorSubtract (end, start, vec);
  1628.     len = VectorNormalize (vec);
  1629.  
  1630.     dec = 1;
  1631.     VectorScale (vec, dec, vec);
  1632.  
  1633.     while (len > 0)
  1634.     {
  1635.         len -= dec;
  1636.  
  1637.         if ( (rand()&7) == 0)
  1638.         {
  1639.             if (!(p = new_particle()))
  1640.                 return;
  1641.             
  1642.             VectorClear (p->accel);
  1643.  
  1644.             p->alpha = 1.0;
  1645.             p->alphavel = -1.0 / (1+frand()*0.2);
  1646.             p->color = 0xdc + (rand()&3);
  1647.             for (j=0 ; j<3 ; j++)
  1648.             {
  1649.                 p->org[j] = move[j] + crand()*5;
  1650.                 p->vel[j] = crand()*20;
  1651.             }
  1652.             p->accel[2] = -PARTICLE_GRAVITY;
  1653.         }
  1654.         VectorAdd (move, vec, move);
  1655.     }
  1656. }
  1657.  
  1658. void CL_ShipExhaust (vec3_t start, vec3_t end, centity_t *old)
  1659. {
  1660.     vec3_t        move;
  1661.     vec3_t        vec;
  1662.     float        len;
  1663.     int            j;
  1664.     cparticle_t    *p;
  1665.     float        dec;
  1666.  
  1667.     VectorCopy (start, move);
  1668.     VectorSubtract (end, start, vec);
  1669.     len = VectorNormalize (vec);
  1670.  
  1671.     dec = 1;
  1672.     VectorScale (vec, dec, vec);
  1673.  
  1674.     while (len > 0)
  1675.     {
  1676.         len -= dec;
  1677.  
  1678.         if ( (rand()&7) == 0)
  1679.         {
  1680.             if (!(p = new_particle()))
  1681.                 return;
  1682.             
  1683.             VectorClear (p->accel);
  1684.  
  1685.             p->alpha = 1.0;
  1686.             p->alphavel = -1.0 / (1+frand()*0.2);
  1687.             p->type = PARTICLE_EXPLOSION;;
  1688.             for (j=0 ; j<3 ; j++)
  1689.             {
  1690.                 p->org[j] = move[j] + crand()*5;
  1691.                 p->vel[j] = crand()*20;
  1692.             }
  1693.             p->accel[2] = -PARTICLE_GRAVITY;
  1694.         }
  1695.         VectorAdd (move, vec, move);
  1696.     }
  1697. }
  1698. /*
  1699. ===============
  1700. CL_RailTrail
  1701.  
  1702. ===============
  1703. */
  1704. void CL_RailTrail (vec3_t start, vec3_t end)
  1705. {
  1706.     vec3_t        move;
  1707.     vec3_t        vec;
  1708.     float        len;
  1709.     int            j;
  1710.     cparticle_t    *p;
  1711.     float        dec;
  1712.     vec3_t        right, up;
  1713.     int            i;
  1714.     float        d, c, s;
  1715.     vec3_t        dir;
  1716.     byte        clr = 0x40;//blue 0x74;
  1717.  
  1718.     VectorCopy (start, move);
  1719.     VectorSubtract (end, start, vec);
  1720.     len = VectorNormalize (vec);
  1721.  
  1722.     MakeNormalVectors (vec, right, up);
  1723.  
  1724.     for (i=0 ; i<len ; i++)
  1725.     {
  1726.         if (!(p = new_particle()))
  1727.             return;
  1728.         
  1729.         VectorClear (p->accel);
  1730.  
  1731.         d = i * 0.1;
  1732.         c = cos(d);
  1733.         s = sin(d);
  1734.  
  1735.         VectorScale (right, c, dir);
  1736.         VectorMA (dir, s, up, dir);
  1737.  
  1738.         p->alpha = 1.0;
  1739.         p->alphavel = -1.0 / (1+frand()*0.2);
  1740.         p->type = PARTICLE_LEADER_BLAST;//clr + (rand()&7);
  1741.         for (j=0 ; j<3 ; j++)
  1742.         {
  1743.             p->org[j] = move[j] + dir[j]*3;
  1744.             p->vel[j] = dir[j]*6;
  1745.         }
  1746.  
  1747.         VectorAdd (move, vec, move);
  1748.     }
  1749.  
  1750.     dec = 0.75;
  1751.     VectorScale (vec, dec, vec);
  1752.     VectorCopy (start, move);
  1753.  
  1754. }
  1755. void CL_LaserTrail (vec3_t start, vec3_t end) //for martians
  1756. {
  1757.     vec3_t        move;
  1758.     vec3_t        vec;
  1759.     float        len;
  1760.     int            j;
  1761.     cparticle_t    *p;
  1762.     float        dec;
  1763.     vec3_t        right, up;
  1764.     int            i;
  1765.     float        d, c, s;
  1766.     vec3_t        dir;
  1767.     byte        clr = 0xd4;
  1768.  
  1769.     VectorCopy (start, move);
  1770.     VectorSubtract (end, start, vec);
  1771.     len = VectorNormalize (vec);
  1772.  
  1773.     MakeNormalVectors (vec, right, up);
  1774.  
  1775.     for (i=0 ; i<len ; i++)
  1776.     {
  1777.         if (!(p = new_particle()))
  1778.             return;
  1779.         
  1780.         VectorClear (p->accel);
  1781.  
  1782.         d = i * 0.02;// * rand();
  1783.         c = 0;//cos(d);
  1784.         s = 0;//sin(d);
  1785.  
  1786.         VectorScale (right, c, dir);
  1787.         VectorMA (dir, s, up, dir);
  1788.  
  1789.         p->alpha = 0.8;
  1790.         p->alphavel = -2.0 / (1+frand()*.2);
  1791.         p->type = PARTICLE_GREEN_LASER2;
  1792.         for (j=0 ; j<3 ; j++)
  1793.         {
  1794.             p->org[j] = move[j] + dir[j]*3;
  1795.             p->vel[j] = dir[j]*6;
  1796.         }
  1797.  
  1798.         VectorAdd (move, vec, move);
  1799.     }
  1800.  
  1801.     dec = 0.75;
  1802.     VectorScale (vec, dec, vec);
  1803.     VectorCopy (start, move);
  1804.  
  1805.     while (len > 0)
  1806.     {
  1807.         len -= dec;
  1808.  
  1809.         if (!(p = new_particle()))
  1810.             return;
  1811.  
  1812.         VectorClear (p->accel);
  1813.  
  1814.         p->alpha = 0.8;
  1815.         p->alphavel = -2.0 / (0.6+frand()*0.2);
  1816.         p->type = PARTICLE_GREEN_LASER1;
  1817.  
  1818.         for (j=0 ; j<3 ; j++)
  1819.         {
  1820.             p->org[j] = move[j] + crand()*3;
  1821.             p->vel[j] = crand()*3;
  1822.             p->accel[j] = 0;
  1823.         }
  1824.  
  1825.         VectorAdd (move, vec, move);
  1826.     }
  1827.     
  1828. }
  1829.  
  1830. void CL_BlasterBeamTrail (vec3_t start, vec3_t end) 
  1831. {
  1832.     vec3_t        move;
  1833.     vec3_t        vec;
  1834.     float        len;
  1835.     int            j;
  1836.     cparticle_t    *p;
  1837.     vec3_t        right, up;
  1838.     byte        clr = 0xd4;
  1839.  
  1840.     VectorCopy (start, move);
  1841.     VectorSubtract (end, start, vec);
  1842.     len = VectorNormalize (vec);
  1843.  
  1844.     MakeNormalVectors (vec, right, up);
  1845.  
  1846.     while (len > 0)
  1847.     {
  1848.         len -= 0.5;
  1849.  
  1850.         if (!(p = new_particle()))
  1851.             return;
  1852.  
  1853.         VectorClear (p->accel);
  1854.  
  1855.         p->alpha = 0.8;
  1856.         p->alphavel = -2.0 / (0.6+frand()*0.2);
  1857.         p->type = PARTICLE_BLASTER_BEAM;
  1858.  
  1859.         for (j=0 ; j<3 ; j++)
  1860.         {
  1861.             p->org[j] = move[j];
  1862.             p->vel[j] = crand()*3;
  1863.             p->accel[j] = 0;
  1864.         }
  1865.  
  1866.         VectorAdd (move, vec, move);
  1867.     }
  1868.     
  1869. }
  1870.  
  1871. void CL_NewLightning (vec3_t start, vec3_t end) 
  1872. {
  1873.     vec3_t        move;
  1874.     vec3_t        vec;
  1875.     float        len;
  1876.     int            j;
  1877.     cparticle_t    *p;
  1878.     float        dec;
  1879.     vec3_t        right, up;
  1880.     int            i;
  1881.     float        skewx, skewy, skewz;
  1882.     float        x, y, z;
  1883.     byte        clr = 0xd4;
  1884.  
  1885.     VectorCopy (start, move);
  1886.     VectorSubtract (end, start, vec);
  1887.     len = VectorNormalize (vec);
  1888.  
  1889.     MakeNormalVectors (vec, right, up);
  1890.  
  1891.     dec = 0.75;
  1892.     VectorScale (vec, dec, vec);
  1893.     VectorCopy (start, move);
  1894.     skewx = skewy = skewz = .1;
  1895.     i = 0;
  1896.     x = y = z = 0;
  1897.  
  1898.     while (len > 0)
  1899.     {
  1900.         len -= dec;
  1901.         i++;
  1902.  
  1903.         if (!(p = new_particle()))
  1904.             return;
  1905.  
  1906.         VectorClear (p->accel);
  1907.  
  1908.         x++;
  1909.         y++;
  1910.         z++;
  1911.  
  1912.         // somehow increment x,y,z in random direction
  1913.         if (i > 10)//reset
  1914.         {
  1915.             i = 0;
  1916.             x = y = z = 0;
  1917.             if (frand() < 0.5)
  1918.                 skewx = skewx * -1;
  1919.             if (frand() < 0.5)
  1920.                 skewy = skewy * -1;
  1921.             if (frand() < 0.5)
  1922.                 skewz = skewz * -1;
  1923.         }
  1924.         
  1925.         p->org[0] = move[0] + skewx * ++x;
  1926.         p->org[1] = move[1] + skewy * ++y;
  1927.         p->org[2] = move[2] + skewz * ++z;
  1928.  
  1929.         p->alpha = 0.8;
  1930.         p->alphavel = -2.0 / (0.6+frand()*0.2);
  1931.         p->type = PARTICLE_LIGHTNING;
  1932.  
  1933.         for (j=0 ; j<3 ; j++)
  1934.         {
  1935.         //    p->org[j] = move[j];
  1936.             p->vel[j] = 0;//crand()*3;
  1937.             p->accel[j] = 0;
  1938.         }
  1939.  
  1940.         VectorAdd (p->org, vec, move);
  1941.     }
  1942.     
  1943. }
  1944. void CL_LaserBlast (vec3_t start, vec3_t end) //for player
  1945. {
  1946.     vec3_t        move;
  1947.     vec3_t        vec;
  1948.     float        len;
  1949.     int            j;
  1950.     cparticle_t    *p;
  1951.     float        dec;
  1952.     vec3_t        right, up;
  1953.     int            i;
  1954.     float        d, c, s;
  1955.     vec3_t        dir;
  1956.     byte        clr = 0xdf;
  1957.  
  1958.     VectorCopy (start, move);
  1959.     VectorSubtract (end, start, vec);
  1960.     len = VectorNormalize (vec);
  1961.  
  1962.     MakeNormalVectors (vec, right, up);
  1963.  
  1964.     for (i=0 ; i<len ; i++)
  1965.     {
  1966.         if (!(p = new_particle()))
  1967.             return;
  1968.         
  1969.         VectorClear (p->accel);
  1970.  
  1971.         d = i * 0.02;// * rand();
  1972.         c = 0;//cos(d);
  1973.         s = 0;//sin(d);
  1974.  
  1975.  
  1976.         VectorScale (right, c, dir);
  1977.         VectorMA (dir, s, up, dir);
  1978.  
  1979.         p->alpha = 0.8;
  1980.         p->alphavel = -1.0 / (1+frand()*0.2);
  1981.         p->type = PARTICLE_BLASTER;
  1982.         for (j=0 ; j<3 ; j++)
  1983.         {
  1984.             p->org[j] = move[j] + dir[j]*3;
  1985.             p->vel[j] = dir[j]*6;
  1986.         }
  1987.  
  1988.         VectorAdd (move, vec, move);
  1989.     }
  1990.  
  1991.     dec = 0.75;
  1992.     VectorScale (vec, dec, vec);
  1993.     VectorCopy (start, move);
  1994.  
  1995.     while (len > 0)
  1996.     {
  1997.         len -= dec;
  1998.  
  1999.         if (!(p = new_particle()))
  2000.             return;
  2001.  
  2002.         VectorClear (p->accel);
  2003.  
  2004.         p->alpha = 0.8;
  2005.         p->alphavel = -1.0 / (0.6+frand()*0.2);
  2006.         p->color = clr + (rand()&2);
  2007.  
  2008.         for (j=0 ; j<3 ; j++)
  2009.         {
  2010.             p->org[j] = move[j] + crand()*3;
  2011.             p->vel[j] = crand()*3;
  2012.             p->accel[j] = 0;
  2013.         }
  2014.  
  2015.         VectorAdd (move, vec, move);
  2016.     }
  2017.     
  2018. }
  2019. void CL_LaserBlast2 (vec3_t start, vec3_t end) //for martian_leader
  2020. {
  2021.     vec3_t        move;
  2022.     vec3_t        vec;
  2023.     float        len;
  2024.     int            j;
  2025.     cparticle_t    *p;
  2026.     float        dec;
  2027.     vec3_t        right, up;
  2028.     int            i;
  2029.     float        d, c, s;
  2030.     vec3_t        dir;
  2031.     byte        clr = 0xdf;
  2032.  
  2033.     VectorCopy (start, move);
  2034.     VectorSubtract (end, start, vec);
  2035.     len = VectorNormalize (vec);
  2036.  
  2037.     MakeNormalVectors (vec, right, up);
  2038.  
  2039.     for (i=0 ; i<len ; i++)
  2040.     {
  2041.         if (!(p = new_particle()))
  2042.             return;
  2043.         
  2044.         VectorClear (p->accel);
  2045.  
  2046.         d = i * 0.02;// * rand();
  2047.         c = 0;//cos(d);
  2048.         s = 0;//sin(d);
  2049.  
  2050.  
  2051.         VectorScale (right, c, dir);
  2052.         VectorMA (dir, s, up, dir);
  2053.  
  2054.         p->alpha = 0.8;
  2055.         p->alphavel = -1.0 / (1+frand()*0.2);
  2056.         p->type = PARTICLE_LEADER_BLAST;
  2057.         for (j=0 ; j<3 ; j++)
  2058.         {
  2059.             p->org[j] = move[j] + dir[j]*3;
  2060.             p->vel[j] = dir[j]*6;
  2061.         }
  2062.  
  2063.         VectorAdd (move, vec, move);
  2064.     }
  2065.  
  2066.     dec = 0.75;
  2067.     VectorScale (vec, dec, vec);
  2068.     VectorCopy (start, move);
  2069.  
  2070.     while (len > 0)
  2071.     {
  2072.         len -= dec;
  2073.  
  2074.         if (!(p = new_particle()))
  2075.             return;
  2076.  
  2077.         VectorClear (p->accel);
  2078.  
  2079.         p->alpha = 0.8;
  2080.         p->alphavel = -1.0 / (0.6+frand()*0.2);
  2081.         p->type = PARTICLE_LEADER_BLAST;
  2082.  
  2083.         for (j=0 ; j<3 ; j++)
  2084.         {
  2085.             p->org[j] = move[j] + crand()*3;
  2086.             p->vel[j] = crand()*3;
  2087.             p->accel[j] = 0;
  2088.         }
  2089.  
  2090.         VectorAdd (move, vec, move);
  2091.     }
  2092.     
  2093. }
  2094.  
  2095. void CL_HeatBlast (vec3_t start, vec3_t end) // for martians
  2096. {
  2097.     vec3_t        move;
  2098.     vec3_t        vec;
  2099.     float        len;
  2100.     int            j;
  2101.     cparticle_t    *p;
  2102.     float        dec;
  2103.     vec3_t        right, up;
  2104.     byte        clr = 0xd4;
  2105.  
  2106.     VectorCopy (start, move);
  2107.     VectorSubtract (end, start, vec);
  2108.     len = VectorNormalize (vec);
  2109.  
  2110.     MakeNormalVectors (vec, right, up);
  2111.  
  2112.     dec = 0.75;
  2113.     VectorScale (vec, dec, vec);
  2114.     VectorCopy (start, move);
  2115.  
  2116.     while (len > 0)
  2117.     {
  2118.         len -= dec;
  2119.  
  2120.         if (!(p = new_particle()))
  2121.             return;
  2122.  
  2123.         VectorClear (p->accel);
  2124.  
  2125.         p->alpha = 0.4;
  2126.         p->alphavel = -1.0 / (0.6+frand()*0.2);
  2127.         p->color = 223 - (rand()&7); + (rand()&2);
  2128.         for (j=0 ; j<3 ; j++)
  2129.         {
  2130.             p->org[j] = move[j] + crand()*5;
  2131.             p->vel[j] = crand()*5;
  2132.             p->accel[j] = 0;
  2133.         }
  2134.  
  2135.         VectorAdd (move, vec, move);
  2136.     }
  2137.     
  2138. }
  2139. // RAFAEL
  2140. /*
  2141. ===============
  2142. CL_IonripperTrail
  2143. ===============
  2144. */
  2145. void CL_IonripperTrail (vec3_t start, vec3_t ent)
  2146. {
  2147.     vec3_t    move;
  2148.     vec3_t    vec;
  2149.     float    len;
  2150.     int        j;
  2151.     cparticle_t *p;
  2152.     int        dec;
  2153.     int     left = 0;
  2154.  
  2155.     VectorCopy (start, move);
  2156.     VectorSubtract (ent, start, vec);
  2157.     len = VectorNormalize (vec);
  2158.  
  2159.     dec = 5;
  2160.     VectorScale (vec, 5, vec);
  2161.  
  2162.     while (len > 0)
  2163.     {
  2164.         len -= dec;
  2165.  
  2166.         if (!(p = new_particle()))
  2167.             return;
  2168.  
  2169.         VectorClear (p->accel);
  2170.  
  2171.         p->alpha = 0.5;
  2172.         p->alphavel = -1.0 / (0.3 + frand() * 0.2);
  2173.         p->color = 0xe4 + (rand()&3);
  2174.  
  2175.         for (j=0; j<3; j++)
  2176.         {
  2177.             p->org[j] = move[j];
  2178.             p->accel[j] = 0;
  2179.         }
  2180.         if (left)
  2181.         {
  2182.             left = 0;
  2183.             p->vel[0] = 10;
  2184.         }
  2185.         else 
  2186.         {
  2187.             left = 1;
  2188.             p->vel[0] = -10;
  2189.         }
  2190.  
  2191.         p->vel[1] = 0;
  2192.         p->vel[2] = 0;
  2193.  
  2194.         VectorAdd (move, vec, move);
  2195.     }
  2196. }
  2197.  
  2198.  
  2199. /*
  2200. ===============
  2201. CL_BubbleTrail
  2202.  
  2203. ===============
  2204. */
  2205. void CL_BubbleTrail (vec3_t start, vec3_t end)
  2206. {
  2207.     vec3_t        move;
  2208.     vec3_t        vec;
  2209.     float        len;
  2210.     int            i, j;
  2211.     cparticle_t    *p;
  2212.     float        dec;
  2213.  
  2214.     VectorCopy (start, move);
  2215.     VectorSubtract (end, start, vec);
  2216.     len = VectorNormalize (vec);
  2217.  
  2218.     dec = 32;
  2219.     VectorScale (vec, dec, vec);
  2220.  
  2221.     for (i=0 ; i<len ; i+=dec)
  2222.     {
  2223.         if (!(p = new_particle()))
  2224.             return;
  2225.  
  2226.         VectorClear (p->accel);
  2227.  
  2228.         p->alpha = 1.0;
  2229.         p->alphavel = -1.0 / (1+frand()*0.2);
  2230.         p->color = 4 + (rand()&7);
  2231.         for (j=0 ; j<3 ; j++)
  2232.         {
  2233.             p->org[j] = move[j] + crand()*2;
  2234.             p->vel[j] = crand()*5;
  2235.         }
  2236.         p->vel[2] += 6;
  2237.  
  2238.         VectorAdd (move, vec, move);
  2239.     }
  2240. }
  2241.  
  2242.  
  2243. /*
  2244. ===============
  2245. CL_FlyParticles
  2246. ===============
  2247. */
  2248. void CL_FlyParticles (vec3_t origin, int count)
  2249. {
  2250.     int            i;
  2251.     cparticle_t    *p;
  2252.     float        angle;
  2253.     float        sr, sp, sy, cr, cp, cy;
  2254.     vec3_t        forward;
  2255.     float        dist = 64;
  2256.     float        ltime;
  2257.     int            beamlength = 4;
  2258.  
  2259.     if (count > NUMVERTEXNORMALS)
  2260.         count = NUMVERTEXNORMALS;
  2261.  
  2262.     if (!avelocities[0][0])
  2263.     {
  2264.         for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++)
  2265.             avelocities[0][i] = (rand()&255) * 0.01;
  2266.     }
  2267.  
  2268.     ltime = (float)cl.time / 1000.0;
  2269.     for (i=0 ; i<count ; i+=2)
  2270.     {
  2271.         if (!(p = new_particle()))
  2272.             return;
  2273.  
  2274.         angle = ltime * avelocities[i][0];
  2275.         sy = sin(angle);
  2276.         cy = cos(angle);
  2277.         angle = ltime * avelocities[i][1];
  2278.         sp = sin(angle);
  2279.         cp = cos(angle);
  2280.         angle = ltime * avelocities[i][2];
  2281.         sr = sin(angle);
  2282.         cr = cos(angle);
  2283.     
  2284.         forward[0] = cp*cy;
  2285.         forward[1] = cp*sy;
  2286.         forward[2] = -sp;
  2287.  
  2288.         dist = sin(ltime + i)*4;
  2289.         p->org[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*beamlength;
  2290.         p->org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*beamlength;
  2291.         p->org[2] = origin[2] + bytedirs[i][2]*dist*16 + forward[2]*beamlength * 4;
  2292.  
  2293.         VectorClear (p->vel);
  2294.         VectorClear (p->accel);
  2295.  
  2296.         p->type = PARTICLE_GREEN_LASER1;
  2297.         p->colorvel = 0;
  2298.  
  2299.         p->alpha = 0.3;
  2300.         p->alphavel = -1.5;
  2301.     }
  2302. }
  2303.  
  2304. void CL_FlyEffect (centity_t *ent, vec3_t origin)
  2305. {
  2306.     int        count;
  2307.     int        starttime;
  2308.  
  2309.     if (ent->fly_stoptime < cl.time)
  2310.     {
  2311.         starttime = cl.time;
  2312.         ent->fly_stoptime = cl.time + 60000;
  2313.     }
  2314.     else
  2315.     {
  2316.         starttime = ent->fly_stoptime - 60000;
  2317.     }
  2318.  
  2319.     count = 128;
  2320.  
  2321.     CL_FlyParticles (origin, count);
  2322. }
  2323.  
  2324.  
  2325. /*
  2326. ===============
  2327. CL_BfgParticles
  2328. ===============
  2329. */
  2330. void CL_BfgParticles (entity_t *ent)
  2331. {
  2332.     int            i;
  2333.     cparticle_t    *p;
  2334.     float        angle;
  2335.     float        sr, sp, sy, cr, cp, cy;
  2336.     vec3_t        forward;
  2337.     float        dist = 64;
  2338.     vec3_t        v;
  2339.     float        ltime;
  2340.     int            beamlength = 16;
  2341.     
  2342.     if (!avelocities[0][0])
  2343.     {
  2344.         for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++)
  2345.             avelocities[0][i] = (rand()&255) * 0.01;
  2346.     }
  2347.  
  2348.  
  2349.     ltime = (float)cl.time / 1000.0;
  2350.     for (i=0 ; i<NUMVERTEXNORMALS ; i++)
  2351.     {
  2352.         angle = ltime * avelocities[i][0];
  2353.         sy = sin(angle);
  2354.         cy = cos(angle);
  2355.         angle = ltime * avelocities[i][1];
  2356.         sp = sin(angle);
  2357.         cp = cos(angle);
  2358.         angle = ltime * avelocities[i][2];
  2359.         sr = sin(angle);
  2360.         cr = cos(angle);
  2361.     
  2362.         forward[0] = cp*cy;
  2363.         forward[1] = cp*sy;
  2364.         forward[2] = -sp;
  2365.  
  2366.         if (!(p = new_particle()))
  2367.             return;
  2368.  
  2369.         dist = sin(ltime + i)*64;
  2370.         p->org[0] = ent->origin[0] + bytedirs[i][0]*dist + forward[0]*beamlength;
  2371.         p->org[1] = ent->origin[1] + bytedirs[i][1]*dist + forward[1]*beamlength;
  2372.         p->org[2] = ent->origin[2] + bytedirs[i][2]*dist + forward[2]*beamlength;
  2373.  
  2374.         VectorClear (p->vel);
  2375.         VectorClear (p->accel);
  2376.  
  2377.         VectorSubtract (p->org, ent->origin, v);
  2378.         dist = VectorLength(v) / 90.0;
  2379.         p->color = floor (0xd0 + dist * 7);
  2380.         p->colorvel = 0;
  2381.  
  2382.         p->alpha = 1.0 - dist;
  2383.         p->alphavel = -100;
  2384.     }
  2385. }
  2386.  
  2387.  
  2388. /*
  2389. ===============
  2390. CL_TrapParticles
  2391. ===============
  2392. */
  2393. // RAFAEL
  2394. void CL_TrapParticles (entity_t *ent)
  2395. {
  2396.     vec3_t        move;
  2397.     vec3_t        vec;
  2398.     vec3_t        start, end;
  2399.     float        len;
  2400.     int            j;
  2401.     cparticle_t    *p;
  2402.     int            dec;
  2403.  
  2404.     ent->origin[2]-=14;
  2405.     VectorCopy (ent->origin, start);
  2406.     VectorCopy (ent->origin, end);
  2407.     end[2]+=64;
  2408.  
  2409.     VectorCopy (start, move);
  2410.     VectorSubtract (end, start, vec);
  2411.     len = VectorNormalize (vec);
  2412.  
  2413.     dec = 5;
  2414.     VectorScale (vec, 5, vec);
  2415.  
  2416.     // FIXME: this is a really silly way to have a loop
  2417.     while (len > 0)
  2418.     {
  2419.         len -= dec;
  2420.  
  2421.         if (!(p = new_particle()))
  2422.             return;
  2423.         VectorClear (p->accel);
  2424.         
  2425.         p->alpha = 1.0;
  2426.         p->alphavel = -1.0 / (0.3+frand()*0.2);
  2427.         p->color = 0xe0;
  2428.         for (j=0 ; j<3 ; j++)
  2429.         {
  2430.             p->org[j] = move[j] + crand();
  2431.             p->vel[j] = crand()*15;
  2432.             p->accel[j] = 0;
  2433.         }
  2434.         p->accel[2] = PARTICLE_GRAVITY;
  2435.  
  2436.         VectorAdd (move, vec, move);
  2437.     }
  2438.  
  2439.     {
  2440.  
  2441.     
  2442.     int            i, j, k;
  2443.     cparticle_t    *p;
  2444.     float        vel;
  2445.     vec3_t        dir;
  2446.     vec3_t        org;
  2447.  
  2448.     
  2449.     ent->origin[2]+=14;
  2450.     VectorCopy (ent->origin, org);
  2451.  
  2452.  
  2453.     for (i=-2 ; i<=2 ; i+=4)
  2454.         for (j=-2 ; j<=2 ; j+=4)
  2455.             for (k=-2 ; k<=4 ; k+=4)
  2456.             {
  2457.                 if (!(p = new_particle()))
  2458.                     return;
  2459.  
  2460.                 p->color = 0xe0 + (rand()&3);
  2461.  
  2462.                 p->alpha = 1.0;
  2463.                 p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02);
  2464.                 
  2465.                 p->org[0] = org[0] + i + ((rand()&23) * crand());
  2466.                 p->org[1] = org[1] + j + ((rand()&23) * crand());
  2467.                 p->org[2] = org[2] + k + ((rand()&23) * crand());
  2468.     
  2469.                 dir[0] = j * 8;
  2470.                 dir[1] = i * 8;
  2471.                 dir[2] = k * 8;
  2472.     
  2473.                 VectorNormalize (dir);                        
  2474.                 vel = 50 + rand()&63;
  2475.                 VectorScale (dir, vel, p->vel);
  2476.  
  2477.                 p->accel[0] = p->accel[1] = 0;
  2478.                 p->accel[2] = -PARTICLE_GRAVITY;
  2479.             }
  2480.     }
  2481. }
  2482.  
  2483.  
  2484. /*
  2485. ===============
  2486. CL_BFGExplosionParticles
  2487. ===============
  2488. */
  2489. //FIXME combined with CL_ExplosionParticles
  2490. void CL_BFGExplosionParticles (vec3_t org)
  2491. {
  2492.     int            i, j;
  2493.     cparticle_t    *p;
  2494.  
  2495.     for (i=0 ; i<256 ; i++)
  2496.     {
  2497.         if (!(p = new_particle()))
  2498.             return;
  2499.  
  2500.         p->color = 0xd0 + (rand()&7);
  2501.  
  2502.         for (j=0 ; j<3 ; j++)
  2503.         {
  2504.             p->org[j] = org[j] + ((rand()%32)-16);
  2505.             p->vel[j] = (rand()%384)-192;
  2506.         }
  2507.  
  2508.         p->accel[0] = p->accel[1] = 0;
  2509.         p->accel[2] = -PARTICLE_GRAVITY;
  2510.         p->alpha = 1.0;
  2511.  
  2512.         p->alphavel = -0.8 / (0.5 + frand()*0.3);
  2513.     }
  2514. }
  2515.  
  2516.  
  2517. /*
  2518. ===============
  2519. CL_TeleportParticles
  2520.  
  2521. ===============
  2522. */
  2523. void CL_TeleportParticles (vec3_t org)
  2524. {
  2525.     int            i, j, k;
  2526.     cparticle_t    *p;
  2527.     float        vel;
  2528.     vec3_t        dir;
  2529.  
  2530.     for (i=-16 ; i<=16 ; i+=4)
  2531.         for (j=-16 ; j<=16 ; j+=4)
  2532.             for (k=-16 ; k<=32 ; k+=4)
  2533.             {
  2534.                 if (!(p = new_particle()))
  2535.                     return;
  2536.  
  2537.                 p->color = 7 + (rand()&7);
  2538.  
  2539.                 p->alpha = 1.0;
  2540.                 p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02);
  2541.                 
  2542.                 p->org[0] = org[0] + i + (rand()&3);
  2543.                 p->org[1] = org[1] + j + (rand()&3);
  2544.                 p->org[2] = org[2] + k + (rand()&3);
  2545.     
  2546.                 dir[0] = j*8;
  2547.                 dir[1] = i*8;
  2548.                 dir[2] = k*8;
  2549.     
  2550.                 VectorNormalize (dir);                        
  2551.                 vel = 50 + (rand()&63);
  2552.                 VectorScale (dir, vel, p->vel);
  2553.  
  2554.                 p->accel[0] = p->accel[1] = 0;
  2555.                 p->accel[2] = -PARTICLE_GRAVITY;
  2556.             }
  2557. }
  2558.  
  2559.  
  2560. /*
  2561. ===============
  2562. CL_AddParticles
  2563. ===============
  2564. */
  2565. void CL_AddParticles (void)
  2566. {
  2567.     cparticle_t        *p, *next;
  2568.     float            alpha;
  2569.     float            time, time2;
  2570.     vec3_t            org;
  2571.     cparticle_t        *active, *tail;
  2572.  
  2573.     active = NULL;
  2574.     tail = NULL;
  2575.  
  2576.     for (p=active_particles ; p ; p=next)
  2577.     {
  2578.         next = p->next;
  2579.  
  2580.         // PMM - added INSTANT_PARTICLE handling for heat beam
  2581.         if (p->alphavel != INSTANT_PARTICLE)
  2582.         {
  2583.             time = (cl.time - p->time)*0.001;
  2584.             alpha = p->alpha + time*p->alphavel;
  2585.             if (alpha <= 0)
  2586.             {    // faded out
  2587.                 p->next = free_particles;
  2588.                 free_particles = p;
  2589.                 continue;
  2590.             }
  2591.         }
  2592.         else
  2593.         {
  2594.             alpha = p->alpha;
  2595.         }
  2596.  
  2597.         p->next = NULL;
  2598.         if (!tail)
  2599.             active = tail = p;
  2600.         else
  2601.         {
  2602.             tail->next = p;
  2603.             tail = p;
  2604.         }
  2605.  
  2606.         if (alpha > 1.0)
  2607.             alpha = 1;
  2608.  
  2609.         time2 = time*time;
  2610.  
  2611.         org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2;
  2612.         org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2;
  2613.         org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2;
  2614.  
  2615.         V_AddParticle (org, p->color, p->type, alpha);
  2616.         // PMM
  2617.         if (p->alphavel == INSTANT_PARTICLE)
  2618.         {
  2619.             p->alphavel = 0.0;
  2620.             p->alpha = 0.0;
  2621.         }
  2622.     }
  2623.  
  2624.     active_particles = active;
  2625. }
  2626.  
  2627.  
  2628. /*
  2629. ==============
  2630. CL_EntityEvent
  2631.  
  2632. An entity has just been parsed that has an event value
  2633.  
  2634. the female events are there for backwards compatability
  2635. ==============
  2636. */
  2637. extern struct sfx_s    *cl_sfx_footsteps[4];
  2638.  
  2639. void CL_EntityEvent (entity_state_t *ent)
  2640. {
  2641.     switch (ent->event)
  2642.     {
  2643.     case EV_ITEM_RESPAWN:
  2644.         S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0);
  2645.         CL_ItemRespawnParticles (ent->origin);
  2646.         break;
  2647.     case EV_PLAYER_TELEPORT:
  2648.         S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0);
  2649.         CL_TeleportParticles (ent->origin);
  2650.         break;
  2651.     case EV_FOOTSTEP:
  2652.         if (cl_footsteps->value)
  2653.             S_StartSound (NULL, ent->number, CHAN_BODY, cl_sfx_footsteps[rand()&3], 1, ATTN_NORM, 0);
  2654.         break;
  2655.     case EV_FALLSHORT:
  2656.         S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0);
  2657.         break;
  2658.     case EV_FALL:
  2659.         S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0);
  2660.         break;
  2661.     case EV_FALLFAR:
  2662.         S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0);
  2663.         break;
  2664.     }
  2665. }
  2666.  
  2667.  
  2668. /*
  2669. ==============
  2670. CL_ClearEffects
  2671.  
  2672. ==============
  2673. */
  2674. void CL_ClearEffects (void)
  2675. {
  2676.     CL_ClearParticles ();
  2677.     CL_ClearDlights ();
  2678.     CL_ClearLightStyles ();
  2679. }
  2680.